fix: double free in checkout_tree_at_recurse
authorDaniel Hast <hast.daniel@protonmail.com>
Fri, 29 Aug 2025 18:17:15 +0000 (14:17 -0400)
committerDaniel Hast <hast.daniel@protonmail.com>
Fri, 29 Aug 2025 18:17:15 +0000 (14:17 -0400)
Both `xattrs` and `modified_xattrs` are declared with `g_autoptr`, but
`xattrs` is later simply assigned to be equal to `modified_xattrs`,
meaning the automatic cleanup is a double-free.

This is fixed by instead using `g_steal_pointer` to assign the old value
of `xattrs` to a temporary variable, which is used to create the new
value.

I believe this is the cause of issue #3303, and this should fix #3303.
(I can consistently reproduce the issue by attempting to deploy a
rechunked image with bootc, and with this patch, the issue no longer
occurs and the deployment succeeds.)

Signed-off-by: Daniel Hast <hast.daniel@protonmail.com>
src/libostree/ostree-repo-checkout.c

index ccddb4882322d512be59d2375bac5f4c6f14b463..aa32ff4a85c349c5652009e429515841299e88b2 100644 (file)
@@ -997,7 +997,6 @@ checkout_tree_at_recurse (OstreeRepo *self, OstreeRepoCheckoutAtOptions *options
   g_autoptr (GVariant) dirtree = NULL;
   g_autoptr (GVariant) dirmeta = NULL;
   g_autoptr (GVariant) xattrs = NULL;
-  g_autoptr (GVariant) modified_xattrs = NULL;
 
   if (!ostree_repo_load_variant (self, OSTREE_OBJECT_TYPE_DIR_TREE, dirtree_checksum, &dirtree,
                                  error))
@@ -1055,8 +1054,8 @@ checkout_tree_at_recurse (OstreeRepo *self, OstreeRepoCheckoutAtOptions *options
     if (sepolicy_enabled && _ostree_sepolicy_host_enabled (options->sepolicy))
       {
         /* We'll set the xattr via setfscreatecon(), so don't do it via generic xattrs below. */
-        modified_xattrs = _ostree_filter_selinux_xattr (xattrs);
-        xattrs = modified_xattrs;
+        g_autoptr (GVariant) old_xattrs = g_steal_pointer (&xattrs);
+        xattrs = _ostree_filter_selinux_xattr (old_xattrs);
 
         if (!_ostree_sepolicy_preparefscreatecon (&fscreatecon, options->sepolicy,
                                                   state->selabel_path_buf->str, mode, error))